<template>
  <div class="container">
    <div class="lc-container">
      <div class="action-bar">
        <el-form ref="form" :model="form" :rules="rules" label-width="100px" size="small">
          <div class="filter-container">
            <div class="filter-item">
              <el-form-item label="表单名称：">
                <el-input v-model="tableComment" disabled size="small" placeholder="请输入表单名称" />
              </el-form-item>
            </div>
            <div class="filter-item">
              <el-form-item label="布局名称：" prop="layoutName">
                <el-input v-model="form.layoutName" size="small" placeholder="请输入布局名称" />
              </el-form-item>
            </div>
            <el-button type="primary" class="filter-item" size="small" :loading="btnSubmitLoading" @click="handleSubmit">
              保存
            </el-button>
            <el-button type="primary" class="filter-item" plain size="small" @click="handlePreview">
              预览
            </el-button>
            <el-button type="danger" class="filter-item" size="small" title="清空后如果不点击保存，还可以刷新浏览器进行恢复" @click="handleEmpty">
              清空
            </el-button>
            <el-button size="small" class="filter-item" @click="handleReturn">
              返回
            </el-button>
          </div>
        </el-form>
      </div>
      <div class="lc-content">
        <div class="left-board">
          <el-scrollbar class="left-scrollbar">
            <div class="components-list">
              <div class="components-title">
                <svg-icon icon-class="component" />输入型组件
              </div>
              <draggable
                class="components-draggable"
                :list="inputComponents"
                :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
                :clone="cloneComponent"
                draggable=".components-item"
                :sort="false"
                @end="onEnd"
              >
                <div
                  v-for="(element, index) in inputComponents"
                  :key="index"
                  class="components-item"
                  @click="addComponent(element)"
                >
                  <div class="components-body">
                    <svg-icon :icon-class="element.tagIcon" />
                    {{ element.label }}
                  </div>
                </div>
              </draggable>
              <div class="components-title">
                <svg-icon icon-class="component" />选择型组件
              </div>
              <draggable
                class="components-draggable"
                :list="selectComponents"
                :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
                :clone="cloneComponent"
                draggable=".components-item"
                :sort="false"
                @end="onEnd"
              >
                <div
                  v-for="(element, index) in selectComponents"
                  :key="index"
                  class="components-item"
                  @click="addComponent(element)"
                >
                  <div class="components-body">
                    <svg-icon :icon-class="element.tagIcon" />
                    {{ element.label }}
                  </div>
                </div>
              </draggable>
              <div class="components-title">
                <svg-icon icon-class="component" /> 布局型组件
              </div>
              <draggable
                class="components-draggable"
                :list="layoutComponents"
                :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
                :clone="cloneComponent"
                draggable=".components-item"
                :sort="false"
                @end="onEnd"
              >
                <div
                  v-for="(element, index) in layoutComponents"
                  :key="index"
                  class="components-item"
                  @click="addComponent(element)"
                >
                  <div class="components-body">
                    <svg-icon :icon-class="element.tagIcon" />
                    {{ element.label }}
                  </div>
                </div>
              </draggable>
              <div class="components-title">
                <svg-icon icon-class="component" /> 系统组件
              </div>
              <draggable
                class="components-draggable"
                :list="[ ...sysComponents.linkComponents, ...sysComponents.selectComponents ]"
                :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
                :clone="cloneComponent"
                draggable=".components-item"
                :sort="false"
                @end="onEnd"
              >
                <div
                  v-for="(element, index) in [ ...sysComponents.linkComponents, ...sysComponents.selectComponents ]"
                  :key="index"
                  class="components-item"
                  @click="addComponent(element)"
                >
                  <div class="components-body">
                    <svg-icon :icon-class="element.tagIcon" />
                    {{ element.label }}
                  </div>
                </div>
              </draggable>
            </div>
          </el-scrollbar>
        </div>

        <div class="center-board">
          <el-scrollbar class="center-scrollbar">
            <el-row class="center-board-row" :gutter="formConf.gutter">
              <el-form
                :size="formConf.size"
                :label-position="formConf.labelPosition"
                :disabled="formConf.disabled"
                :label-width="formConf.labelWidth + 'px'"
              >
                <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup">
                  <draggable-item
                    v-for="(element, index) in drawingList"
                    :key="element.renderKey"
                    :drawing-list="drawingList"
                    :element="element"
                    :index="index"
                    :active-id="activeId"
                    :form-conf="formConf"
                    @activeItem="activeFormItem"
                    @copyItem="drawingItemCopy"
                    @deleteItem="drawingItemDelete"
                  />
                </draggable>
                <div v-show="!drawingList.length" class="empty-info">
                  从左侧拖入或点选组件进行表单设计
                </div>
              </el-form>
            </el-row>
          </el-scrollbar>
        </div>

      </div>
    </div>
    <right-panel
      :tableId="tableId"
      :activeData="activeData"
      :formConf="formConf"
      :fields="drawingList"
      :showField="!!drawingList.length"
      @tag-change="tagChange"
    />
    <FormPreview
      ref="FormPreview"
      size="100%"
    />
    <input id="copyNode" type="hidden">
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import FormPreview from './components/FormPreview'
import RightPanel from './components/RightPanel'
import DraggableItem from './components/DraggableItem'

import {
  inputComponents, selectComponents, layoutComponents, sysComponents, formConf
} from '@/views/workflow/components/generator/config'
import logo from '@/assets/logo.png'
import { getIdGlobal, saveIdGlobal } from '@/views/workflow/utils/generator/db'
import { getInfoById, create, update } from '@/api/workflow/form/layout'
import enums from '@/views/workflow/utils/enum'
import { isNumeric } from 'echarts/lib/util/number'

let oldActiveId
let tempActiveData
// const idGlobal = getIdGlobal()
const idGlobal = new Date().valueOf()

export default {
  components: {
    draggable,
    FormPreview,
    RightPanel,
    DraggableItem
  },
  data() {
    return {
      logo,
      idGlobal,
      formConf,
      inputComponents,
      selectComponents,
      layoutComponents,
      sysComponents,
      labelWidth: 100,
      drawingList: [],
      drawingData: {},
      activeId: '',
      formData: {},
      generateConf: null,
      showFileName: false,
      activeData: {},
      tableId: '', // 表单id
      tableComment: '', // 表单名称
      layoutId: '', // 布局id
      form: { // 布局
        layoutId: '',
        layoutName: '',
        html: '' // 对应this.formData
      },
      rules: {
        layoutName: [{ required: true, message: '请输入布局名称', trigger: 'blur' }]
      },
      btnSubmitLoading: false
    }
  },
  computed: {
  },
  watch: {
    // eslint-disable-next-line func-names
    'activeData.label': function(val, oldVal) {
      if (this.activeData.tag === 'quill-editor') {
        if (
          this.activeData.options.placeholder === undefined ||
          !this.activeData.tag ||
          oldActiveId !== this.activeId
        ) {
          return
        }
        const endStr = this.activeData.options.placeholder.substr(this.activeData.options.placeholder.indexOf(oldVal))
        this.activeData.options.placeholder = this.activeData.options.placeholder.replace(endStr, '') + val
      } else {
        if (
          this.activeData.placeholder === undefined ||
          !this.activeData.tag ||
          oldActiveId !== this.activeId
        ) {
          return
        }
        const endStr = this.activeData.placeholder.substr(this.activeData.placeholder.indexOf(oldVal))
        this.activeData.placeholder = this.activeData.placeholder.replace(endStr, '') + val
      }
    },
    'activeData.vModel': function(val, oldVal) {
      this.drawingList.forEach(item => {
        if (item.valueType && item.valueData) {
          switch(item.valueType) {
            case Object.keys(enums.VALUE_TYPE)[1]: // SQL
              break
            case Object.keys(enums.VALUE_TYPE)[2]: // SQL_LIST
              break
            case Object.keys(enums.VALUE_TYPE)[3]: // DICTIONARIES
              break
            case Object.keys(enums.VALUE_TYPE)[4]: // JAVASCRIPT_MATH
            // this.formData.starTime.valueOf()-20000 / (1000*60*60*24)
              // item.vModel = 5 // eval.call(this, item.valueData)
              break
            case Object.keys(enums.VALUE_TYPE)[5]: // JAVA_MATH
              break
            default:
              break
          }
        }
      })
    },
    activeId: {
      handler(val) {
        oldActiveId = val
      },
      immediate: true
    },
    // drawingList: {
    //   handler(val) {
    //     // saveDrawingList(val)
    //     if (val.length === 0) this.idGlobal = 100
    //   },
    //   deep: true
    // },
    // idGlobal: {
    //   handler(val) {
    //     saveIdGlobal(val)
    //   },
    //   immediate: true
    // }
  },
  created() {
    this.tableId = this.$route.query.tableId
    this.tableComment = this.$route.query.tableComment
    this.layoutId = this.$route.query.layoutId
    // this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
    this.fetchLayoutData()
  },
  mounted() {
    // if (Array.isArray(drawingListInDB) && drawingListInDB.length > 0) {
    //   this.drawingList = drawingListInDB
    // } else {
    //   this.drawingList = drawingDefalut
    // }
    // this.activeFormItem(this.drawingList[0])
    // if (formConfInDB) {
    //   this.formConf = formConfInDB
    // }
  },
  methods: {
    fetchLayoutData() { // 获取布局信息
      if (!this.layoutId) return
      getInfoById(this.layoutId).then(res => {
        this.form = res.data
        const formData = res.data.html ? JSON.parse(res.data.html) : {}
        this.drawingList = formData.fields
        this.formConf = { ...this.formConf, ...formData }
        delete this.formConf.fields
      })
    },
    AssembleFormData() { // 格式化Form的Json
      this.formData = {
        fields: this.drawingList,
        ...this.formConf
      }
    },
    handlePreview() { // 点击预览
      this.AssembleFormData()
      this.$refs.FormPreview.onOpen(this.formData)
    },
    handleEmpty() { // 点击清空
      const _this = this
      this.$confirm({
        title: '提示',
        content: `确定要清空所有组件吗？`,
        okText: '确定',
        okType: 'danger',
        cancelText: '取消',
        centered: true,
        onOk() {
          _this.drawingList = []
          // _this.idGlobal = 100
        }
      })
    },
    handleSubmit() { // 点击保存
      this.AssembleFormData()
      this.handleSave()
    },
    handleSave() { // 提交保存
      if (!this.formData || !this.formData.fields || !this.formData.fields.length) {
        this.$message.warning('表单设计不能为空')
      }
      this.$refs.form.validate(valid => {
        if (valid) {
          this.btnSubmitLoading = true
          const post = {
            ...this.form,
            tableId: this.tableId,
            html: JSON.stringify(this.formData) // 对应this.formData
          }
          if (this.layoutId) { // 修改
            update(post).then(res => {
              this.$message.success('修改成功')
              this.btnSubmitLoading = false
              // this.$router.push({ path: '/workflow/form/set' })
            }).catch(res => {
              this.btnSubmitLoading = false
            })
          } else { // 新增
            create(post).then(res => {
              this.$message.success('新增成功')
              this.btnSubmitLoading = false
              // this.$router.push({ name: 'designFormList' })
              this.handleReturn()
            }).catch(res => {
              this.btnSubmitLoading = false
            })
          }
        }
      })
    },
    activeFormItem(element) { // 激活正在编辑的组件
      this.activeData = element
      this.activeId = element.formId
    },
    onEnd(obj, a) {
      if (obj.from !== obj.to) {
        this.activeData = tempActiveData
        this.activeId = this.idGlobal
      }
    },
    addComponent(item) { // 点击左侧组件添加一个新的组件至表单
      const clone = this.cloneComponent(item)
      this.drawingList.push(clone)
      this.activeFormItem(clone)
    },
    cloneComponent(origin) { // 从左侧拖拽一个新的组件至表单
      const clone = JSON.parse(JSON.stringify(origin))
      // clone.formId = ++this.idGlobal
      this.idGlobal = new Date().valueOf()
      clone.formId = this.idGlobal
      clone.span = formConf.span
      clone.renderKey = +new Date() // 改变renderKey后可以实现强制更新组件
      if (!clone.layout) clone.layout = 'colFormItem'
      if (clone.layout === 'colFormItem') {
        clone.vModel = `field${this.idGlobal}`
        if (clone.tag === 'quill-editor') { // 富文本
          clone.options.placeholder !== undefined && (clone.options.placeholder += clone.label)
        } else {
          clone.placeholder !== undefined && (clone.placeholder += clone.label)
        }
        tempActiveData = clone
      } else if (clone.layout === 'rowFormItem') { // 普通表单组件
        delete clone.label
        clone.componentName = `row${this.idGlobal}`
        clone.gutter = this.formConf.gutter
        tempActiveData = clone
      } else if (clone.layout === 'textItem') {  // 文本
        delete clone.label
        clone.componentName = `text${this.idGlobal}`
        tempActiveData = clone
      } else if (clone.layout === 'tabsItem') { // tabs选项卡
        delete clone.label
        clone.componentName = `tabs${this.idGlobal}`
        tempActiveData = clone
      } else if (clone.layout === 'cardItem') { // 卡片
        delete clone.label
        clone.componentName = `card${this.idGlobal}`
        tempActiveData = clone
      } else if (clone.layout === 'tableItem') { // 表格
        delete clone.label
        clone.componentName = `table${this.idGlobal}`
        tempActiveData = clone
      }
      return tempActiveData
    },
    drawingItemCopy(item, parent) { // 点击组件的复制按钮复制一个相同组件
      let clone = JSON.parse(JSON.stringify(item))
      clone = this.createIdAndKey(clone)
      parent.push(clone)
      this.activeFormItem(clone)
    },
    createIdAndKey(item) {
      // item.formId = ++this.idGlobal
      this.idGlobal = new Date().valueOf()
      item.formId = this.idGlobal
      item.renderKey = +new Date()
      if (item.layout === 'colFormItem') {
        item.vModel = `field${this.idGlobal}`
      } else if (item.layout === 'rowFormItem') {
        item.componentName = `row${this.idGlobal}`
      } else if (item.layout === 'textItem') {
        item.componentName = `text${this.idGlobal}`
      } else if (item.layout === 'tabsItem') {
        item.componentName = `tabs${this.idGlobal}`
      } else if (item.layout === 'cardItem') {
        item.componentName = `card${this.idGlobal}`
      } else if (item.layout === 'tableItem') {
        item.componentName = `table${this.idGlobal}`
      }
      if (item.layout === 'tabsItem') {
        item.tabs.forEach(tab => {
          if (Array.isArray(tab.children)) {
            tab.children = tab.children.map(childItem => this.createIdAndKey(childItem))
          }
        })
      } else {
        if (Array.isArray(item.children)) {
          item.children = item.children.map(childItem => this.createIdAndKey(childItem))
        }
      }
      return item
    },
    drawingItemDelete(index, parent) {
      parent.splice(index, 1)
      this.$nextTick(() => {
        const len = this.drawingList.length
        if (len) {
          this.activeFormItem(this.drawingList[len - 1])
        }
      })
    },
    tagChange(newTag) {
      newTag = this.cloneComponent(newTag)
      newTag.vModel = this.activeData.vModel
      newTag.formId = this.activeId
      newTag.span = this.activeData.span
      delete this.activeData.tag
      delete this.activeData.tagIcon
      delete this.activeData.document
      Object.keys(newTag).forEach(key => {
        if (this.activeData[key] !== undefined
          && typeof this.activeData[key] === typeof newTag[key]) {
          newTag[key] = this.activeData[key]
        }
      })
      this.activeData = newTag
      this.updateDrawingList(newTag, this.drawingList)
    },
    updateDrawingList(newTag, list) {
      const index = list.findIndex(item => item.formId === this.activeId)
      if (index > -1) {
        list.splice(index, 1, newTag)
      } else {
        list.forEach(item => {
          if (Array.isArray(item.children)) this.updateDrawingList(newTag, item.children)
        })
      }
    },
    handleReturn() {
      if (this.tableId) {
        this.$router.push({
          name: 'designFormList', 
          params: {
            tableId: this.tableId
          }
        })
      } else {
        this.$router.go(-1)
      }
    }
  }
}
</script>

<style lang='scss'>
  @import '@/views/workflow/styles/generator_home.scss';
  .ql-toolbar.ql-snow {
    line-height: normal;
  }
</style>
